<?php


namespace App\Service\Chat;


use App\Constants\Chat\RedisKey;
use App\Exception\BusinessException;
use App\Model\Chat\ChatFriend;
use App\Model\Chat\ChatGroup;
use App\Model\Chat\Group;
use App\Model\Chat\GroupMember;
use App\Pool\Redis;
use App\Service\BaseService;
use App\Model\Chat\ChatList;
use App\Service\SenderService;
use Hyperf\WebSocketServer\Sender;
use Hyperf\Di\Annotation\Inject;
use App\Constants\Chat\Chat;

class ChatService extends BaseService
{
    /**
     * @Inject
     * @var Sender $sender
     */
    protected $sender;

    public static function getUidByFd(string $fd)
    {
        return Redis::getInstance()->hGet(RedisKey::ONLINE_USER_FD_KEY, (string)$fd);
    }


    public static function isOnline($uid)
    {
        return Redis::getInstance()->hGet(RedisKey::ONLINE_USER_ID_KEY, (string)$uid);
    }


    /**
     * 获取用户会话列表
     */
    public function getUserChatLists($user_id): array
    {
        $redis = Redis::getInstance();
        $key = RedisKey::USER_CHAT_LIST_KEY . $user_id;
        $cache = $redis->get($key);
        if ($cache) {
            return unserialize($cache);
        }
        $list = ChatList::query()->select('*')->where(['user_id' => $user_id])->get()->toArray();
        if (empty($list)) {
            return [];
        }
        $redis->set($key, serialize($list));
        return $list;
    }

    /**
     * 获取用户会话信息
     */
    public function getUserChat($user_id, $chat_id): array
    {
        $redis = Redis::getInstance();

        $key = RedisKey::USER_CHAT_KEY . $chat_id . ':' . $user_id;
        $cache = $redis->get($key);
        if ($cache) {
            return unserialize($cache);
        }
        $cache = ChatList::query()->select('*')->where([
            'chat_id' => $chat_id,
            'user_id' => $user_id])->first();
        if (empty($cache)) {
            return [];
        }
        $redis->set($key, serialize($cache->toArray()));
        return $cache->toArray();
    }


    /**
     * 清除用户会话列表缓存
     * @param mixed $user_id
     * @param string $chat_id
     */
    public static function clearUserChatList($user_id, $chat_id = '')
    {
        if ($chat_id) {
            $key = RedisKey::USER_CHAT_LIST_KEY . $chat_id . ':' . $user_id;
        } else {
            $key = RedisKey::USER_CHAT_LIST_KEY . 'all:' . $user_id;
        }
        Redis::getInstance()->del($key);
    }

    /**
     * 发送系统消息
     * @param $user_id
     * @param string $msg
     * @param string $cmd
     * @return bool
     */
    public function sendSystemMsg($user_id, $msg, $cmd = 'chat'): bool
    {
        $data = [
            'type' => Chat::CHAT_TYPE_SYSTEM,
            'chat_id' => 0,
            'user_id' => 0,
            'msg_type' => Chat::CHAT_MESSAGE_TYPE_TEXT,
            'content' => $msg,
            'user_info' => ''
        ];
        return SenderService::getInstance()->sendToUid($user_id, $cmd, $data);
    }

    /**
     * 获取会话信息
     * @param $user_id
     * @param $chat_id
     * @return array
     */
    public function getChat($user_id, $chat_id): array
    {
        if (!$chat_list = self::getUserChat($user_id, $chat_id)) {
            throw new BusinessException('没有这条会话,发送消息失败!');
        }
        switch ($chat_list['type']) {
            //好友
            case 0:
                /** 如果是对话，检测对方是不是把自己删除了 */
                $friend_id = $chat_list['friend_id'];
                $friend_chat_list = self::getUserChatList($friend_id, $chat_id);
                if (!$friend_chat_list) {
                    throw new BusinessException('你还不是对方好友,发送消息失败');
                }
                break;
            //群聊
            case 1:
                /** 如果是群聊禁言中不能发送消息 */
                $chat_group = GroupService::getGroupInfo($chat_id);
                if (!$chat_group) {
                    throw new BusinessException('群已被解散');
                }
                $user_ids = explode(',', $chat_group['user_ids']);
                if (!in_array($user_id, $user_ids)) {
                    throw new BusinessException('您尚未加群');
                }
                /** 被禁言了或者群状态为禁言中，群主和管理员不被禁言 */
                if ($chat_group['is_forbid'] || ($chat_group['is_forbid'] && $chat_group['admin_id'] != $user_id)) {
                    throw new BusinessException('群已禁言');
                }
                break;
            default:
                throw new BusinessException('未知对话类型');
        }
        //会话删除状态，重新激活它
        if ($chat_list['status'] == 0) {
            self::saveChatList($chat_id, true);
            //self::clearUserChatList( $user_id);
            /** 发送通知用户重新获取会话列表*/
            SenderService::getInstance()->sendToUid($user_id, ['chat_id' => $chat_id], 'getChatList');
        }
        return $chat_list;
    }

    /**
     * 保存会话数据
     * @param $chat_list
     * @param bool $save_db
     */
    public static function saveChatList($chat_list, $save_db = false): bool
    {
        $key = RedisKey::USER_CHAT_LIST_KEY . $chat_list['chat_id'] . ':' . $chat_list['user_id'];
        $redis = Redis::getInstance();
        $redis->set($key, $chat_list);
        if ($save_db) {
            ChatList::where(['chat_id' => $chat_list['chat_id'], 'user_id' => $chat_list['user_id']])->update($chat_list);
        }
        //更新所有会话列表
        $all_chat_list = self::getUserChatList($chat_list['user_id']);
        if (!empty($all_chat_list)) {
            foreach ($all_chat_list as $k => $item) {
                if ($item['chat_id'] == $chat_list['chat_id']) {
                    $all_chat_list[$k] = $chat_list;
                }
            }
            $key = RedisKey::USER_CHAT_LIST_KEY . 'all:' . $chat_list['user_id'];
            $redis->set($key, $all_chat_list);
        }
        return true;
    }

}
